package com.lu.test.aop;

import org.aspectj.util.FileUtil;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.util.FileCopyUtils;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@SuppressWarnings({"rawtypes", "unchecked"})
public class JDKProxyTest1 {
	public static void main(String[] args) {
		InterTest interTest = new InterTestImpl();
		MyInvocationHandler<InterTest> myInvocationHandler = new MyInvocationHandler(interTest);
		// 这里的 返回的实例是 interfaces的实例，只能强转成接口的实例。不能是实现类
		// 因为 proxy 是居于接口新增了一个实现类。
		InterTest proxy = (InterTest) Proxy.newProxyInstance(
				InterTestImpl.class.getClassLoader(),
				InterTestImpl.class.getInterfaces(),
				myInvocationHandler
		);

		System.out.println(proxy.test());

		// jdk创建proxy类的实现
		createProxyClass(interTest.getClass().getName(), InterTest.class);

	}

	private static void createProxyClass(String clzName, Class<?>... interfaces) {
		String proxyClzName = clzName + "Proxy";
		// 核心代码 生成proxyClass 文件
		byte[] bytes = ProxyGenerator.generateProxyClass(proxyClzName, interfaces);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(proxyClzName + ".class");
			fos.write(bytes);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != fos) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}

class MyInvocationHandler<T> implements InvocationHandler {
	// 被代理对象
	private T target;

	public MyInvocationHandler(T target) {
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("before");
		Object result = method.invoke(target, args);
		System.out.println("after");
		return result;
	}
}

interface InterTest {
	String test();
}

class InterTestImpl implements InterTest {
	@Override
	public String test() {
		System.out.println("hello world");
		return "result";
	}
}
